package com.okex.demo.service;

import com.alibaba.fastjson.JSONObject;
import com.okex.demo.config.WebSocketEventListener;
import com.okex.demo.model.Account;
import com.okex.demo.model.OrderInfo;
import com.okex.demo.model.PositionInfo;
import com.okex.demo.model.TickerInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.event.EventListener;
import org.springframework.dao.OptimisticLockingFailureException;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 持仓数据轮询服务
 * 始终执行持仓信息查询和业务逻辑处理，但仅在有WebSocket连接时才推送数据
 */
@Slf4j
@Service
public class PositionPollingService {

    @Autowired
    private OkexApiService okexApiService;

    @Autowired
    private AccountService accountService;
    @Autowired
    private OrderService orderService;
    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    @Value("${okex.position.polling.interval:3000}")
    private long pollingInterval; // 默认3秒查询一次

    @Value("${okex.default.inst-id:BTC-USDT}")
    private String defaultInstId;

    private final AtomicBoolean isRunning = new AtomicBoolean(false);
    private final AtomicBoolean hasWebSocketConnections = new AtomicBoolean(false);
    private ScheduledExecutorService executorService;
    private Date lastUpdateTime;

    // 用于账户锁的Map
    private final Map<String, Object> accountLocks = new ConcurrentHashMap<>();

    // 最大重试次数
    private static final int MAX_RETRY_COUNT = 3;

    @PostConstruct
    public void init() {
        log.info("持仓数据轮询服务初始化");
        // 立即启动查询任务，不需要等待WebSocket连接
        startPolling();
    }

    @PreDestroy
    public void shutdown() {
        stopPolling();
    }

    /**
     * 监听WebSocket连接事件
     */
    @EventListener
    public void handleWebSocketConnectionEvent(WebSocketEventListener.WebSocketConnectionEvent event) {
        // 只更新WebSocket连接状态，不影响轮询任务的运行
        hasWebSocketConnections.set(event.isConnected());
        log.info("WebSocket连接状态更新: {}", hasWebSocketConnections.get() ? "有连接" : "无连接");
    }

    /**
     * 启动数据轮询
     */
    public synchronized void startPolling() {
        if (isRunning.get()) {
            log.debug("持仓数据轮询任务已经在运行中");
            return;
        }

        log.info("启动持仓数据轮询任务，间隔: {}毫秒", pollingInterval);
        executorService = Executors.newSingleThreadScheduledExecutor(r -> {
            Thread thread = new Thread(r, "position-polling-thread");
            thread.setDaemon(true);
            return thread;
        });
        executorService.scheduleAtFixedRate(this::pollData, 0, pollingInterval, TimeUnit.MILLISECONDS);
        isRunning.set(true);
    }

    /**
     * 停止数据轮询
     */
    public synchronized void stopPolling() {
        if (!isRunning.get()) {
            return;
        }

        log.info("停止持仓数据轮询任务");
        if (executorService != null) {
            executorService.shutdown();
            try {
                if (!executorService.awaitTermination(5, TimeUnit.SECONDS)) {
                    executorService.shutdownNow();
                }
            } catch (InterruptedException e) {
                executorService.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
        isRunning.set(false);
    }

    /**
     * 执行数据查询和处理
     */
    private void pollData() {
        try {
            log.debug("开始获取持仓信息...");
            List<PositionInfo> positions = okexApiService.getPositions();

            // 设置更新时间
            Date now = new Date();
            lastUpdateTime = now;

            // 处理持仓信息
            processPositions(positions, now);

            // 只有在有WebSocket连接时才推送数据
            if (hasWebSocketConnections.get()) {
                // 推送持仓信息到WebSocket
                messagingTemplate.convertAndSend("/topic/positions", positions);
                log.info("已推送持仓信息: {} 条", positions.size());
            } else {
                log.debug("无WebSocket连接，跳过推送持仓信息");
            }

        } catch (Exception e) {
            log.error("持仓数据轮询任务执行异常: {}", e.getMessage(), e);
        }
    }

    /**
     * 处理持仓信息
     */
    private void processPositions(List<PositionInfo> positions, Date updateTime) {
        if (positions.isEmpty()) {
            return;
        }

        // 单独处理每个持仓
        for (PositionInfo position : positions) {
            try {
                // 设置更新时间
                position.setUpdateTime(updateTime);

                // 处理单个持仓
                processSinglePosition(position);
            } catch (Exception e) {
                log.error("处理持仓 {} 出错: {}", position.getInstId(), e.getMessage(), e);
            }
        }
    }

    /**
     * 处理单个持仓
     */
    @Transactional(isolation = Isolation.REPEATABLE_READ)
    public void processSinglePosition(PositionInfo position) {
        String instId = position.getInstId();

        // 获取账户锁
        Object lock = getAccountLock(instId);

        synchronized (lock) {
            try {
                // 从数据库获取最新的账户数据
                Optional<Account> accountOpt = accountService.findByInstId(instId);

                if (!accountOpt.isPresent()) {
                    log.warn("未找到交易对 {} 的账户配置，跳过处理", instId);
                    return;
                }

                Account account = accountOpt.get();

                // 根据持仓模式分别处理
                switch (position.getMgnMode()) {
                    case "cross":
                        // 判断持仓方向
                        if (position.getPosSide().equals("long")) {
                            // 全仓多仓判断止盈
                            boolean profit = processLongCrossStopProfit(position, account);
                            if (profit) {
                                // 全仓多仓加减仓
                                processLongCrossReplenish(position, account);
                            }
                            // 全仓多仓转逐仓
                            //processCrossToIsolatedShort(position, account);
                        } else {
                            // 全仓空仓止盈
                            boolean profit = processShortCrossStopProfit(position, account);
                            if (profit) {
                                // 全仓空仓加减仓
                                processShortCrossReplenish(position, account);
                            }
                            // 全仓空仓转逐仓
                            //processCrossToIsolatedLong(position, account);
                        }
                        break;
                    /*case "isolated":
                        if (position.getPosSide().equals("long")) {
                            processLongIsolatedPosition(position, account);
                        } else {
                            processShortIsolatedPosition(position, account);
                        }
                        break;*/
                }

                // 保存账户配置（带重试）
                saveAccountWithRetry(account, MAX_RETRY_COUNT);

            } catch (Exception e) {
                log.error("处理持仓 {} 交易逻辑错误: {}", position.getInstId(), e.getMessage(), e);
            }
        }
    }

    /**
     * 获取账户锁
     */
    private Object getAccountLock(String instId) {
        return accountLocks.computeIfAbsent(instId, k -> new Object());
    }

    /**
     * 带重试的账户保存
     */
    private void saveAccountWithRetry(Account account, int maxRetries) {
        int retryCount = 0;
        boolean saved = false;

        while (!saved && retryCount < maxRetries) {
            try {
                accountService.saveWithFieldPreservation(account);
                saved = true;
                log.debug("成功保存账户配置: {}", account.getInstId());
            } catch (OptimisticLockingFailureException e) {
                retryCount++;
                log.warn("账户 {} 保存失败 (乐观锁冲突), 重试 {}/{}", account.getInstId(), retryCount, maxRetries);

                if (retryCount < maxRetries) {
                    // 从数据库刷新账户数据
                    Optional<Account> refreshedAccount = accountService.findById(account.getId());
                    if (refreshedAccount.isPresent()) {
                        // 保留当前修改
                        Account freshAccount = refreshedAccount.get();
                        updateAccountFields(freshAccount, account);
                        account = freshAccount;
                    }

                    try {
                        // 重试前小延迟
                        Thread.sleep(100 * retryCount);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        break;
                    }
                }
            } catch (Exception e) {
                log.error("保存账户 {} 失败: {}", account.getInstId(), e.getMessage(), e);
                break;
            }
        }

        if (!saved) {
            log.error("账户 {} 保存失败，已达到最大重试次数", account.getInstId());
        }
    }

    /**
     * 更新账户字段（从源账户到目标账户）
     */
    private void updateAccountFields(Account target, Account source) {
        // 只更新可能被修改的字段
        target.setCrossLongReplenishCount(source.getCrossLongReplenishCount());
        target.setCrossShortReplenishCount(source.getCrossShortReplenishCount());
        target.setCrossLongCost(source.getCrossLongCost());
        target.setCrossShortCost(source.getCrossShortCost());
        target.setCrossToIsolatedShortPriceDiff(source.getCrossToIsolatedShortPriceDiff());
        target.setCrossToIsolatedLongCost(source.getCrossToIsolatedLongCost());
        target.setIsolatedLongReplenishCount(source.getIsolatedLongReplenishCount());
        target.setIsolatedShortReplenishCount(source.getIsolatedShortReplenishCount());
        target.setIsolatedLongCost(source.getIsolatedLongCost());
        target.setIsolatedShortCost(source.getIsolatedShortCost());
        target.setIsTransferIsolatedShort(source.getIsTransferIsolatedShort());
        target.setIsTransferIsolatedLong(source.getIsTransferIsolatedLong());
    }

    /*全仓多仓止盈*/
    private boolean processLongCrossStopProfit(PositionInfo info, Account account) {
        boolean isp = true;
        if (info.getUpl().compareTo(account.getCrossTakeProfit()) >= 0) {
            // 平多
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "sell", "long", info.getAvailPos().toPlainString());
            if (isPlaced) {
                // 全仓保证金张数,此处使用全仓保证金D
                String sz = calculateOrderSize(
                        info,
                        account.getLeverage(),
                        info.getLast(),
                        account.getCrossMargin().doubleValue(),
                        account.getFaceValue().doubleValue()
                );
                // 开多
                isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "buy", "long", sz);
                if (isPlaced) {
                    // 全仓多仓补仓次数恢复到默认状态
                    account.setCrossLongReplenishCount(1);
                    // 全仓多仓成本恢复到默认状态
                    account.setCrossLongCost(BigDecimal.ZERO);
                    // 全仓转逐仓空仓成本恢复到默认状态
                    //account.setCrossToIsolatedShortPriceDiff(BigDecimal.ZERO);
                    isp = false;
                }
            }
        }
        return isp;
    }

    /*全仓多仓加减仓*/
    private void processLongCrossReplenish(PositionInfo info, Account account) {
        // 获取多仓补仓次数
        int f = account.getCrossLongReplenishCount();
        // 获取全仓多仓成本
        BigDecimal h;
        if (account.getCrossLongCost().compareTo(BigDecimal.ZERO) == 0) {
            h = info.getAvgPx();
            account.setCrossLongCost(h);
        } else {
            h = account.getCrossLongCost();
        }

        // 判断补仓
        if (info.getLast().compareTo(h.subtract(account.getCrossPriceDiff().multiply(new BigDecimal(f)))) <= 0) {
            //多仓补仓价格=多仓成本 – 价差 * 多仓补仓次数
            BigDecimal bigDecimal = account.getCrossLongCost().subtract(account.getCrossPriceDiff().multiply(new BigDecimal(f)));
            // 全仓保证金张数,此处使用全仓价差保证金E
            String sz = calculateOrderSize(
                    info,
                    account.getLeverage(),
                    account.getFaceValue(),
                    account.getCrossPriceDiffMargin().doubleValue(),
                    bigDecimal.doubleValue()
            );


            // 开多
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "buy", "long", sz);
            if (isPlaced) {
                // 多仓补仓次数加1
                account.setCrossLongReplenishCount(f + 1);
            }
        }

        // 判断减仓
        if (f >= 2) {
            if (info.getLast().compareTo(h.subtract(account.getCrossPriceDiff().multiply(new BigDecimal(f - 2)))) >= 0) {
                // 多仓减仓价格=多仓成本 – 价差 * （多仓补仓次数 – 2）
                BigDecimal bigDecimal = account.getCrossLongCost().subtract(account.getCrossPriceDiff().multiply(new BigDecimal(f - 2)));
                // 全仓保证金张数,此处使用全仓价差保证金E
                String sz = calculateOrderSize(
                        info,
                        account.getLeverage(),
                        account.getFaceValue(),
                        account.getCrossPriceDiffMargin().doubleValue(),
                        bigDecimal.doubleValue()
                );
                // 平多
                boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "sell", "long", sz);
                if (isPlaced) {
                    // 多仓补仓次数减1
                    account.setCrossLongReplenishCount(f - 1);
                }
            }
        }
    }

    /*全仓转逐仓空仓*/
    private void processCrossToIsolatedShort(PositionInfo info, Account account) {
        // 判断是否全仓转逐仓空仓
        if (account.getIsTransferIsolatedShort()) {
            // 判断全仓转逐仓空仓成本
            BigDecimal k;
            if (account.getCrossToIsolatedShortPriceDiff().compareTo(BigDecimal.ZERO) == 0) {
                k = account.getCrossLongCost().subtract(account.getConversionPriceDiff());
            } else {
                k = account.getCrossToIsolatedShortPriceDiff();
            }

            if (info.getLast().compareTo(k) <= 0) {
                // 设置杠杆倍数
                setLeverage(info.getInstId(), account.getLeverage(), "isolated", "short");

                // 逐仓保证金张数,此处使用逐仓保证金O
                String sz = calculateOrderSize(
                        info,
                        account.getLeverage(),
                        account.getFaceValue(),
                        account.getIsolatedMargin().doubleValue(),
                        account.getFaceValue().doubleValue()
                );

                // 开逐仓空仓
                boolean isPlaced = placeOrder(info.getInstId(), "isolated", "sell", "short", sz);
                if (isPlaced) {
                    // 不再转移逐仓空仓
                    account.setIsTransferIsolatedShort(false);
                }
            }
        }
    }

    /*全仓空仓止盈*/
    private boolean processShortCrossStopProfit(PositionInfo info, Account account) {
        boolean br = true;
        if (info.getUpl().compareTo(account.getCrossTakeProfit()) >= 0) {
            // 平空仓
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "buy", "short", info.getAvailPos().toPlainString());
            if (isPlaced) {
                // 全仓保证金张数,此处使用全仓保证金D
                String sz = calculateOrderSize(
                        info,
                        account.getLeverage(),
                        info.getLast(),
                        account.getCrossMargin().doubleValue(),
                        account.getFaceValue().doubleValue()
                );
                // 开空仓
                isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "sell", "short", sz);
                if (isPlaced) {
                    // 全仓空仓补仓次数恢复到默认状态
                    account.setCrossShortReplenishCount(1);
                    // 全仓空仓成本恢复到默认状态
                    account.setCrossShortCost(BigDecimal.ZERO);
                    // 全仓转逐仓多仓成本恢复到默认状态
                    //account.setCrossToIsolatedLongCost(BigDecimal.ZERO);
                    br = false;
                }
            }
        }
        return br;
    }

    /*全仓空仓加减仓*/
    private void processShortCrossReplenish(PositionInfo info, Account account) {
        // 获取空仓补仓次数
        int g = account.getCrossShortReplenishCount();
        // 获取全仓空仓成本
        BigDecimal i;
        if (account.getCrossShortCost().compareTo(BigDecimal.ZERO) == 0) {
            i = info.getAvgPx();
            account.setCrossShortCost(i);
        } else {
            i = account.getCrossShortCost();
        }

        // 判断补仓
        if (info.getLast().compareTo(i.add(account.getCrossPriceDiff().multiply(new BigDecimal(g)))) >= 0) {
            //空仓补仓价格=空仓成本 + 价差 * 空仓补仓次数
            BigDecimal bigDecimal = account.getCrossShortCost().add(account.getCrossPriceDiff().multiply(new BigDecimal(g)));
            // 全仓保证金张数,此处使用全仓价差保证金E
            String sz = calculateOrderSize(
                    info,
                    account.getLeverage(),
                    account.getFaceValue(),
                    account.getCrossPriceDiffMargin().doubleValue(),
                    bigDecimal.doubleValue()
            );
            // 开空
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "sell", "short", sz);
            if (isPlaced) {
                // 空仓补仓次数加1
                account.setCrossShortReplenishCount(g + 1);
            }
        }

        // 判断减仓
        if (g >= 2) {
            if (info.getLast().compareTo(i.add(account.getCrossPriceDiff().multiply(new BigDecimal(g - 2)))) <= 0) {
                //空仓减仓价格=空仓成本 + 价差 * （空仓补仓次数 -2）
                BigDecimal reduceTargetPrice = account.getCrossLongCost().add(account.getCrossPriceDiff().multiply(new BigDecimal(g - 2)));
                // 全仓保证金张数,此处使用全仓价差保证金E
                String sz = calculateOrderSize(
                        info,
                        account.getLeverage(),
                        account.getFaceValue(),
                        account.getCrossPriceDiffMargin().doubleValue(),
                        reduceTargetPrice.doubleValue()
                );
                // 平空
                boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "buy", "short", sz);
                if (isPlaced) {
                    // 空仓补仓次数减1
                    account.setCrossShortReplenishCount(g - 1);
                }
            }
        }
    }

    /*全仓转逐仓多仓*/
    private void processCrossToIsolatedLong(PositionInfo info, Account account) {
        // 判断是否全仓转逐仓多仓
        if (account.getIsTransferIsolatedLong()) {
            // 判断全仓转逐仓多仓成本
            BigDecimal k;
            if (account.getCrossToIsolatedLongCost().compareTo(BigDecimal.ZERO) == 0) {
                k = account.getCrossShortCost().add(account.getConversionPriceDiff());
            } else {
                k = account.getCrossToIsolatedLongCost();
            }

            if (info.getLast().compareTo(k) >= 0) {
                // 设置杠杆倍数
                setLeverage(info.getInstId(), account.getLeverage(), "isolated", "long");

                // 逐仓保证金张数,此处使用逐仓保证金O
                String sz = calculateOrderSize(
                        info,
                        account.getLeverage(),
                        account.getFaceValue(),
                        account.getIsolatedMargin().doubleValue(),
                        account.getFaceValue().doubleValue()
                );

                // 开逐仓多仓
                boolean isPlaced = placeOrder(info.getInstId(), "isolated", "buy", "long", sz);
                if (isPlaced) {
                    // 不再转移逐仓多仓
                    account.setIsTransferIsolatedLong(false);
                }
            }
        }
    }

    /*逐仓多仓处理*/
    private void processLongIsolatedPosition(PositionInfo info, Account account) {
        // 逐仓多仓补仓次数
        int q = account.getIsolatedLongReplenishCount();
        // 逐仓多仓成本
        BigDecimal v;
        if (account.getIsolatedLongCost().compareTo(BigDecimal.ZERO) == 0) {
            v = info.getAvgPx();
            account.setIsolatedLongCost(v);
        } else {
            v = account.getIsolatedLongCost();
        }

        // 逐仓多仓加仓
        if (info.getLast().compareTo(v.add(account.getIsolatedPriceDiff().multiply(new BigDecimal(q)))) >= 0) {
            // 计算逐仓保证金张数
            String sz = calculateOrderSize(
                    info,
                    account.getLeverage(),
                    account.getFaceValue(),
                    account.getIsolatedPriceDiffMargin().doubleValue(),
                    account.getFaceValue().doubleValue()
            );

            // 开多加仓
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "buy", "long", sz);
            if (isPlaced) {
                // 加仓次数加1
                account.setIsolatedLongReplenishCount(q + 1);
            }
        }

        // 逐仓多仓平仓并开空
        BigDecimal closeTargetPrice = v.add(
                account.getIsolatedPriceDiff().multiply(new BigDecimal(q - 1))
        ).subtract(account.getIsolatedPriceDiff().divide(new BigDecimal(2)));

        if (info.getLast().compareTo(closeTargetPrice) <= 0) {
            // 平多
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "sell", "long", info.getAvailPos().toPlainString());
            if (isPlaced) {

                // 将平仓价上传到全仓转逐仓多仓成本
                account.setCrossToIsolatedLongCost(
                        v.add(account.getIsolatedPriceDiff().multiply(new BigDecimal(q - 1)))
                );

                // 逐仓补仓次数恢复到默认状态1
                account.setIsolatedLongReplenishCount(1);
                // 逐仓多仓成本恢复到默认状态0
                account.setIsolatedLongCost(BigDecimal.ZERO);
                // 是否转移逐仓多仓恢复到默认状态
                account.setIsTransferIsolatedLong(true);
            }

           /* // 计算逐仓保证金张数
            String sz = calculateOrderSize(
                info,
                account.getLeverage(),
                account.getIsolatedPriceDiffMargin().doubleValue(),
                account.getFaceValue().doubleValue()
            );

            // 开空
            placeOrder(info.getInstId(), info.getMgnMode(), "sell", "short", sz);*/
        }
    }

    /*逐仓空仓处理*/
    private void processShortIsolatedPosition(PositionInfo info, Account account) {
        // 逐仓空仓补仓次数
        int r = account.getIsolatedShortReplenishCount();
        // 逐仓空仓成本
        BigDecimal w;
        if (account.getIsolatedShortCost().compareTo(BigDecimal.ZERO) == 0) {
            w = info.getAvgPx();
            account.setIsolatedShortCost(w);
        } else {
            w = account.getIsolatedShortCost();
        }

        // 逐仓空仓补仓
        if (info.getLast().compareTo(w.subtract(account.getIsolatedPriceDiff().multiply(new BigDecimal(r)))) <= 0) {
            // 计算逐仓保证金张数
            String sz = calculateOrderSize(
                    info,
                    account.getLeverage(),
                    account.getFaceValue(),
                    account.getIsolatedPriceDiffMargin().doubleValue(),
                    account.getFaceValue().doubleValue()
            );

            // 开空补仓
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "sell", "short", sz);
            if (isPlaced) {

                // 加仓次数加1
                account.setIsolatedShortReplenishCount(r + 1);
            }
        }

        // 逐仓空仓平仓
        BigDecimal closeTargetPrice = w.subtract(
                account.getIsolatedPriceDiff().multiply(new BigDecimal(r - 1))
        ).add(account.getIsolatedPriceDiff().divide(new BigDecimal(2)));

        if (info.getLast().compareTo(closeTargetPrice) >= 0) {
            // 平空
            boolean isPlaced = placeOrder(info.getInstId(), info.getMgnMode(), "buy", "short", info.getAvailPos().toPlainString());
            if (isPlaced) {

                // 将平仓价上传到全仓转逐仓空仓成本
                account.setCrossToIsolatedShortPriceDiff(
                        w.subtract(account.getIsolatedPriceDiff().multiply(new BigDecimal(r - 1)))
                );

                // 逐仓补仓次数恢复到默认状态1
                account.setIsolatedShortReplenishCount(1);
                // 逐仓空仓成本恢复到默认状态0
                account.setIsolatedShortCost(BigDecimal.ZERO);
                // 是否转移逐仓空仓恢复到默认状态
                account.setIsTransferIsolatedShort(true);
            }

           /* // 计算逐仓保证金张数
            String sz = calculateOrderSize(
                info,
                account.getLeverage(),
                account.getIsolatedPriceDiffMargin().doubleValue(),
                account.getFaceValue().doubleValue()
            );

            // 开多
            placeOrder(info.getInstId(), info.getMgnMode(), "buy", "long", sz);*/
        }
    }

    /**
     * 更新持仓的最新价格
     */
    private void updatePositionLastPrice(PositionInfo position) {
        try {
            if (position.getInstId() != null && !position.getInstId().isEmpty()) {
                // 获取最新行情
                TickerInfo ticker = okexApiService.getTicker(position.getInstId());
                if (ticker != null && ticker.getLast() != null) {
                    position.setLast(ticker.getLast());
                }
            }
        } catch (Exception e) {
            log.warn("更新持仓 {} 最新价格失败: {}", position.getInstId(), e.getMessage());
        }
    }

    /*下单*/
    private boolean placeOrder(String instId, String mgnMode, String side, String posSide, String sz) {
        boolean isPlaced = false;
        // 保存订单记录
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setInstId(instId);
        orderInfo.setTdMode(mgnMode);
        orderInfo.setSide(side);
        orderInfo.setPosSide(posSide);
        orderInfo.setSz(new BigDecimal(sz));
//                orderInfo.setAmount(amount);
        orderInfo.setCreateTime(new Date());
        try {
            // 使用OkexApiService进行下单，该服务已经封装了API调用
            JSONObject result = okexApiService.placeOrder(instId, mgnMode, side, posSide, sz);
            if (result != null && result.getInteger("code") == 0) {
                log.info("下单成功: instId={}, mgnMode={}, side={}, posSide={}, sz={}",
                        instId, mgnMode, side, posSide, sz);
                orderInfo.setCode(0);
                orderInfo.setMsg("成功");
                isPlaced = true;
            } else {
                String errorCode = result != null ? String.valueOf(result.get("code")) : "unknown";
                String errorMsg = result != null ? String.valueOf(result.get("msg")) : "unknown";
                log.error("下单失败: instId={}, mgnMode={}, side={}, posSide={}, sz={}, code={}, msg={}",
                        instId, mgnMode, side, posSide, sz, errorCode, errorMsg);
                orderInfo.setCode(Integer.parseInt(errorCode));
                orderInfo.setMsg(errorMsg);
                isPlaced = false;
            }
        } catch (Exception e) {
            log.error("下单异常: instId={}, mgnMode={}, side={}, posSide={}, sz={}, error={}",
                    instId, mgnMode, side, posSide, sz, e.getMessage(), e);
            orderInfo.setCode(500);
            orderInfo.setMsg(e.getMessage());
            isPlaced = false;
        }
        // 保存订单记录
        orderService.saveOrder(orderInfo);
        return isPlaced;
    }

    /*设置杠杆*/
    private void setLeverage(String instId, String lever, String mgnMode, String posSide) {
        try {
            // 使用OkexApiService中的placeOrder方法，它内部会处理杠杆设置
            // 创建一个最小下单量的订单来触发杠杆设置
            JSONObject result = okexApiService.placeOrder(instId, mgnMode,
                    "long".equals(posSide) ? "buy" : "sell",
                    posSide, "1", lever);

            if (result != null && result.getInteger("code") == 0) {
                log.info("设置杠杆成功: instId={}, lever={}, mgnMode={}, posSide={}",
                        instId, lever, mgnMode, posSide);
            } else {
                String errorCode = result != null ? String.valueOf(result.get("code")) : "unknown";
                String errorMsg = result != null ? String.valueOf(result.get("msg")) : "unknown";
                log.error("设置杠杆失败: instId={}, lever={}, mgnMode={}, posSide={}, code={}, msg={}",
                        instId, lever, mgnMode, posSide, errorCode, errorMsg);
            }
        } catch (Exception e) {
            log.error("设置杠杆异常: instId={}, lever={}, mgnMode={}, posSide={}, error={}",
                    instId, lever, mgnMode, posSide, e.getMessage(), e);
        }
    }

    /**
     *
     * @param info
     * @param lever 杠杆
     * @param margin 保证金
     * @param faceValue 价格
     * @return
     */
    /*计算订单数量*/
    private String calculateOrderSize(PositionInfo info, String lever,BigDecimal price, double margin, double faceValue) {
        try {

            if (price == null || price.compareTo(BigDecimal.ZERO) <= 0) {
                log.error("计算订单数量失败: 面值为空或小于等于0");
                return "1"; // 默认值
            }

            // 记录计算参数
            log.debug("计算订单数量参数: instId={}, price={}, margin={}, leverage={}, faceValue={}",
                    info.getInstId(), price, margin, lever, faceValue);

            // 计算合约面值（单位：USD）
            BigDecimal contractValue = price.multiply(new BigDecimal(faceValue));

            // 确保面值不为0，避免除以0的错误
            if (contractValue.compareTo(BigDecimal.ZERO) <= 0) {
                log.error("计算订单数量失败: 合约面值为0或负数");
                return "1"; // 默认值
            }

            // 计算可买入的合约数量
            BigDecimal marginAmount = new BigDecimal(margin);
            BigDecimal leverNum = new BigDecimal(lever);

            // 张数 = 保证金*杠杆倍数 / (面值*价格)
            BigDecimal size = marginAmount.multiply(leverNum).divide(contractValue, 2, BigDecimal.ROUND_HALF_UP);

            // 取整，确保是整数，符合交易所lot size要求
//            size = size.setScale(2, BigDecimal.ROUND_HALF_UP);

            // 确保至少为1
            if (size.compareTo(BigDecimal.ONE) < 0) {
                size = BigDecimal.ONE;
            }

            String result = size.stripTrailingZeros().toPlainString();
            log.debug("计算订单数量结果: instId={}, size={}", info.getInstId(), result);

            return result;
        } catch (Exception e) {
            log.error("计算订单数量异常: instId={}, error={}", info.getInstId(), e.getMessage(), e);
            return "1"; // 默认值
        }
    }

    /**
     * 手动触发一次查询
     */
    public void triggerPoll() {
        if (isRunning.get()) {
            pollData();
        } else {
            log.warn("持仓数据轮询服务未运行，无法触发查询");
        }
    }

    /**
     * 获取最后更新时间
     */
    public Date getLastUpdateTime() {
        return lastUpdateTime;
    }

    /**
     * 检查服务是否正在运行
     */
    public boolean isRunning() {
        return isRunning.get();
    }
}
